\section{Introduction}

In the definition of the \commonlisp{} \cite{ansi:common:lisp}
metaobject protocol in the book by Kiczales et al
\cite{Kiczales:1991:AMP:574212} (also known as the AMOP), the generic
function \mml{} plays a role that is very
different from most of the other generic functions that are part of
the metaobject protocol.

According to the book, the function has four parameters, all required:

\begin{enumerate}
\item A generic function metaobject.
\item A (possibly uninitialized) method metaobject.
\item A lambda expression.
\item An environment object.
\end{enumerate}

The main difference between \mml{} and other
generic functions defined by the metaobject protocol is that
\mml{} is called as part of the expansion code
for the \texttt{defmethod} macro, whereas other generic functions are
called at execution time.

The AMOP book states that the generic function passed as the first
argument may be different from the one that the method is ultimately
going to be added to.  This possibility seems to exist to handle the
situation where a \texttt{defgeneric} form is followed by a
\texttt{defmethod} form in the same file.  In this situation, the
\commonlisp{} standard clearly states that the file compiler does not
create the generic function at compile time.  Therefore, when the
corresponding \texttt{defmethod} form is expanded (and therefore
\mml{} is called), the generic function does not
yet exist.  It will be created only when the compiled file is loaded
into the \commonlisp{} system.

The AMOP book also states that the method object passed as second
argument may be uninitialized, suggesting that the \emph{class
  prototype} of the method class to be instantiated may be passed as
the second argument.

The third argument is a lambda expression corresponding to the body of
the \texttt{defmethod} form.  The purpose of
\mml{} is to wrap this lambda expression in
another lambda expression called the \emph{method lambda} which is
ultimately compiled in order to yield the \emph{method function}.

The default method lambda returned by an invocation of
\mml{} is a
lambda expression with two parameters.  The first parameter is a list
of all the arguments to the generic function.  The second parameter is
a list of next methods that can be invoked using
\texttt{call\--next\--method} from the body of the method.  Therefore
\mml{} also provides definitions of
\texttt{call\--next\--method} and \texttt{next-method-p} that are
lexically inside the lambda expression it returns.

It is important that the method lambda is returned as part of the
expansion of the \texttt{defmethod} macro and that it is then
processed in the same environment as that of the \texttt{defmethod}
form itself, so that when the \texttt{defmethod} macro call is
evaluated in an environment that is not the \emph{null lexical
  environment}, that environment is taken into account when the method
lambda is processed.  For example, code like this one:

\begin{verbatim}
    (let ((x 10))
      (defmethod foo ((y integer))
        (+ x y)))
\end{verbatim}

\noindent
should work as expected.

Finally, the fourth argument to \mml{} is an
environment object.
